package com.rbcs.flow.service;

import java.util.Date;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.rbcs.base.model.Project;
import com.rbcs.borrow.model.Borrow;
import com.rbcs.budget.model.Budget;
import com.rbcs.budget.model.ProjectBudget;
import com.rbcs.flow.FlowConstants;
import com.rbcs.flow.model.Flow;
import com.rbcs.flow.model.Node;
import com.rbcs.reimb.model.Reimb;
import com.systop.common.modules.dept.model.Dept;
import com.systop.common.modules.dept.service.DeptManager;
import com.systop.common.modules.security.user.model.User;
import com.systop.core.Constants;
import com.systop.core.service.BaseGenericsManager;

/***
 * 流程表管理Manager
 * 
 * @author ShangHua
 */
@Service
public class FlowManager extends BaseGenericsManager<Flow> {

	@Autowired
	private DeptManager deptManager;

	/**
	 * 根据借款单ID得到流程表对应的实体
	 * 
	 * @return
	 */
	public Flow getFlowByBorrowId(Integer borrowId) {
		String hql = "from Flow f where f.borrow.id = ? ";
		return findObject(hql, borrowId);
	}

	/**
	 * 根据还款单ID得到流程表对应的实体
	 * 
	 * @return
	 */
	public Flow getFlowByRePayId(Integer rePayId) {
		String hql = "from Flow f where f.rePay.id = ? ";
		return findObject(hql, rePayId);
	}

	/**
	 * 根据报销单ID得到流程表对应的实体
	 * 
	 * @return
	 */
	public Flow getFlowByReimbId(Integer reimbId) {
		String hql = "from Flow f where f.reimb.id = ? ";
		return findObject(hql, reimbId);
	}
	
	/**
	 * 根据预算ID得到流程表对应的实体
	 * 
	 * @return
	 */
	public Flow getFlowByBudgetId(Integer budgetId) {
		String hql = "from Flow f where f.budget.id = ? ";
		return findObject(hql, budgetId);
	}

	// 审核通过后会修改流程的付款状态为：未付款
	@SuppressWarnings("unused")
	private String convertPayStatus(String flowStatus) {
		if (FlowConstants.AUDIT_PASS.equals(flowStatus)) {
			return Constants.NO;
		} else {
			return null;
		}
	}

	/**
	 * 流程审核
	 */
	@Transactional
	public void saveAuditResult(Flow flow) {
		if (flow != null && flow.getId() != null) {
			//这个注释尚华加
			if (flow.getBorrow() != null) {// 借款
				auditBorrow(flow);
			} else if (flow.getReimb() != null) {// 报销
				auditReimb(flow);
			} else if (flow.getBudget() != null) {// 预算
				auditBudget(flow);
			}
		}

	}

	// 更新借款单
	private void auditBorrow(Flow flow) {
		Borrow borrow = flow.getBorrow();// 借款单
		save(flow);// 更新流程信息
		getDao().saveOrUpdate(borrow);// 更新借款单信息
	}

	// 更新报销单
	private void auditReimb(Flow flow) {
		Reimb reimb = flow.getReimb();// 报销单
		save(flow);// 更新流程信息
		getDao().saveOrUpdate(reimb);// 更新报销单
	}

	// 更新预算
	private void auditBudget(Flow flow) {

	}

	/**
	 * 根据部门编号生成节点，并绑定流程
	 * 
	 * @param flow
	 * @param DeptSerialNo
	 */
	@Transactional
	private void saveNodes(Flow flow, String deptSerialNo) {
		// 获得审批流程涉及的部门
		List<Dept> depts = deptManager.getDeptsBySerialNo(deptSerialNo);
		Dept dept = null;
		for (int i = 0; i < depts.size(); i++) {
			dept = depts.get(i);
			// 获得部门负责人信息
			Map<String, String> map = deptManager.getManagersMap(dept.getId());
			Node node = createNode(flow, i + 1,
					map.get(FlowConstants.AUDITOR_IDS_KEY),
					map.get(FlowConstants.AUDITOR_NAMES_KEY), dept);
			getDao().saveOrUpdate(node);
		}
	}

	/**
	 * 根据项目生成节点，绑定流程，项目审批节点就项目负责人一个
	 * 
	 * @param flow
	 * @param project
	 */
	@Transactional
	private void saveNodes(Flow flow, Project project) {
		Node node = createNode(flow, 1, project.getManagerIds(),
				project.getManagerNames(), null);
		getDao().saveOrUpdate(node);
	}

	/**
	 * 创建部门预算审批流程
	 */
	@Transactional
	public void createBudgetFlow(Budget budget) {
		User proposer = budget.getCreater();// 获得申请人
		Flow flow = createFlow(proposer.getDept().getName() + "预算申请");
		flow.setProposer(proposer);// 申请人
		flow.setBudget(budget);
		save(flow);// 保存流程
		saveNodes(flow, proposer.getDept().getSerialNo());
	}
	
	/**
	 * 创建项目预算审批流程
	 */
	@Transactional
	public void createProjectBudgetFlow(ProjectBudget prjBudget) {
		Flow flow = createFlow(prjBudget.getProject().getName() + "预算申请");
		flow.setProjectBudget(prjBudget);//关联项目预算
		flow.setProposer(prjBudget.getCreater());// 申请人
		save(flow);// 保存流程
		saveNodes(flow, prjBudget.getProject());
	}

	/**
	 * 创建借款[部门借款、项目借款]审批流程
	 */
	@Transactional
	public void createBorrowFlow(Borrow borrow) {
		User borrower = borrow.getBorrower();// 获得申请人
		Flow flow = createFlow(borrower.getName() + "借款申请");
		flow.setProposer(borrower);// 申请人
		flow.setBorrow(borrow);
		save(flow);// 保存流程
		if (borrow.getProject() == null) {
			saveNodes(flow, borrower.getDept().getSerialNo());
		} else {// 项目借款流程节点创建
			saveNodes(flow, borrow.getProject());
		}
	}

	/**
	 * 创建报销[部门报销、项目报销]审批流程
	 */
	@Transactional
	public void createReimbFlow(Reimb reimb) {
		User reimber = reimb.getReimber();// 获得申请人
		Flow flow = createFlow(reimber.getName() + "报销申请");
		flow.setProposer(reimber);// 申请人
		flow.setReimb(reimb);
		save(flow);// 保存流程
		if (reimb.getProject() == null) {
			saveNodes(flow, reimb.getDept().getSerialNo());
		} else {// 项目借款流程节点创建
			saveNodes(flow, reimb.getProject());
		}
	}

	/**
	 * 创建一个新的流程对象
	 * 
	 * @param title
	 * @return
	 */
	private Flow createFlow(String title) {
		Flow flow = new Flow();
		flow.setTitle(title);
		flow.setCreateDate(new Date());
		flow.setStatus(FlowConstants.FLOW_START);
		return flow;
	}

	/**
	 * 创建一个新的流程节点
	 * 
	 * @return
	 */
	private Node createNode(Flow flow, Integer orderId, String managerIds,
			String managerNames, Dept dept) {
		Node node = new Node();
		node.setDept(dept);// 设置部门
		node.setFlow(flow);// 关联流程
		node.setOrderId(orderId);// 设置节点审批顺序
		node.setAuditorIds(managerIds);// 设置节点审批人
		node.setAuditorNames(managerNames);
		node.setStatus(FlowConstants.AUDIT_PENDING);// 初始化节点状态:待审批
		return node;
	}
}
